package org.qq120011676.fileserver.fileserver.config;

import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.HandlerMethodValidationException;

import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
@RestControllerAdvice
@RequiredArgsConstructor
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ExceptionResp exception(Exception e) {
        log.error(e.getMessage(), e);
        ExceptionResp resp = new ExceptionResp();
        resp.setMessage(e.getMessage());
        return resp;
    }

    @ExceptionHandler(HandlerMethodValidationException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ExceptionResp handlerMethodValidationException(HandlerMethodValidationException e) {
        log.error(e.getMessage(), e);
        String message = e.getAllErrors()
                .stream()
                .map(o -> {
                    String defaultMessage = o.getDefaultMessage();
                    Object[] arguments = o.getArguments();
                    String[] codes = o.getCodes();
                    String argumentsStr = Arrays.stream(Optional.ofNullable(arguments)
                                    .orElse(new Object[]{}))
                            .filter(v -> v instanceof DefaultMessageSourceResolvable)
                            .map(v -> ((DefaultMessageSourceResolvable) v).getDefaultMessage())
                            .map(v -> MessageFormat.format("【{0}】", v))
                            .collect(Collectors.joining("、"));
                    return MessageFormat.format("{0}{1}", argumentsStr, defaultMessage);
                })
                .collect(Collectors.joining(";"));
        ExceptionResp resp = new ExceptionResp();
        resp.setMessage(message);
        return resp;
    }


    @Data
    public static class ExceptionResp {
        private String message;
    }
}
